import { StrTool } from './StrTool'

// noinspection JSUnusedGlobalSymbols
/**
 * RandomTool
 * @author 冰凝
 * @date 2022-09-19 10:01:51
 **/
export class RandomTool {

    /**
     * 纯数字
     * @type {number[]}
     */
    public static NUMBER = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
    /**
     * 纯数字不含4
     * @type {number[]}
     */
    public static FRIENDLY_NUMBERS = [ 0, 1, 2, 3, 5, 6, 7, 8, 9 ]
    /**
     * 小写字母
     * @type {string[]}
     */
    public static LOWER_CASE_LETTERS = [
        'a', 'b', 'c', 'd', 'e', 'f', 'g',
        'h', 'i', 'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's', 't',
        'u', 'v', 'w', 'x', 'y', 'z',
    ]
    /**
     * 大写字母
     * @type {string[]}
     */
    public static UPPERCASE_LETTER = [
        'A', 'B', 'C', 'D', 'E', 'F', 'G',
        'H', 'I', 'J', 'K', 'L', 'M', 'N',
        'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z',
    ]

    /**
     * 随机数生成
     * @param pond {number[] | string []}
     * @param length {number} 每个字符串长度
     * @param size {number} 字符串数量
     * @return string[]
     */
    public static randomStringArr(pond: number[] | string[], length: number, size: number): string[] {
        if (!this.checkMaxSizeOk(pond.length, length, size)) {
            throw new Error('基数 / 位数 过低, 无法生成 ' + size + ' 个')
        }

        const res = {}
        for (let i = 0; i < size; i++) {
            res[this.randomString(pond, length)] = 1
        }
        while (Object.keys(res).length < size) {
            res[this.randomString(pond, length)] = 1
        }
        return Object.keys(res)
    }

    /**
     *
     * @param base 基数
     * @param length 位数 (指数)
     * @param size 期望最大值
     * @return 如果能够生成至少 size 个 值, 返回 true; 否则 false
     */
    static checkMaxSizeOk(base: number, length: number, size: number): boolean {
        const max = Math.pow(base, length)
        return max > size
    }

    /**
     * 使用指定字符池 pond, 生成 指定长度 length 的字符串
     * @param pond {number [] | string []}
     * @param length {number} 长度 最终字符串长度
     * @return string
     */
    public static randomString(pond: number[] | string[], length: number): string {
        let res = new Array(length)
        const pondLength = pond.length
        for (let i = 1; i <= length; i++) {
            let randomIndex = this.randomNumber(0, pondLength)
            res.push(pond[randomIndex])
        }
        return res.join(StrTool.EMPTY)
    }

    /**
     * 获得一个随机整数 介于: [min, max)
     * @param min {number}
     * @param max {number}
     * @return {number}
     */
    public static randomNumber(min: number, max: number): number {
        return Math.floor(Math.random() * (max - min)) + min
    }

    /**
     * 获得一个随机整数 介于: [min, max]
     * @param min {number}
     * @param max {number}
     * @return {number}
     */
    public static randomNumberMax(min: number, max: number): number {
        return Math.floor(Math.random() * (max - min + 1)) + min
    }
}
